﻿using System.Diagnostics;

namespace DimensionsHelper.LanguageService.Syntax;

public class OptionStatement : Statement
{
    private readonly SyntaxToken _optionKeywordToken;
    private SyntaxToken? _settingKeywordToken;

    internal OptionStatement(SyntaxNode? parent, SyntaxToken optionKeywordToken, SyntaxToken? settingKeywordToken) :
        base(SyntaxKinds.OptionStatement, parent)
    {
        SetChildField(ref _optionKeywordToken, optionKeywordToken);
        SetChildNullableField(ref _settingKeywordToken, SyntaxToken.IsNullOrEmpty, settingKeywordToken);
    }


    /// <summary>
    ///     可以是 Implicit | Explicit | GlobalVariables
    /// </summary>
    public SyntaxToken? SettingKeyWordToken => _settingKeywordToken;


    /// <summary>
    ///     Option 关键字
    /// </summary>
    public SyntaxToken OptionKeywordToken => _optionKeywordToken;


    /// <summary>
    ///     如果是Option Implicit，返回<see langword="true" />
    /// </summary>
    public bool IsImplicit => SettingKeyWordToken?.IsNode(SyntaxKinds.ImplicitKeywordToken) == true;


    /// <summary>
    ///     如果是Option Explicit，返回<see langword="true" />
    /// </summary>
    public bool IsExplicit => SettingKeyWordToken?.IsNode(SyntaxKinds.ExplicitKeywordToken) == true;


    /// <summary>
    ///     如果是Option GlobalVariables，返回<see langword="true" />
    /// </summary>
    public bool IsGlobalVariables =>
        SettingKeyWordToken?.IsNode(SyntaxKinds.GlobalSqlVariablesKeywordToken) == true;


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, OptionKeywordToken, SettingKeyWordToken);
    }


    public OptionStatement Update(SyntaxToken settingKeywordToken)
    {
        SetChildNullableField(ref _settingKeywordToken, SyntaxToken.IsNullOrEmpty, settingKeywordToken);
        return this;
    }
}


public static partial class NodeFactory
{
    public static OptionStatement CreateOptionStatement(SyntaxNode? parent, SyntaxToken optionKeywordToken,
        SyntaxToken? settingKeywordToken)
    {
        Debug.Assert(optionKeywordToken.IsNode(SyntaxKinds.OptionKeywordToken));
        Debug.Assert(settingKeywordToken == null || settingKeywordToken.IsOneOfNode(
            SyntaxKinds.ImplicitKeywordToken,
            SyntaxKinds.ExplicitKeywordToken,
            SyntaxKinds.GlobalVariablesKeywordToken));
        return new OptionStatement(parent, optionKeywordToken, settingKeywordToken);
    }
}